package com.smfx.yxt.service.impl;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import com.smfx.yxt.common.Const;
import com.smfx.yxt.common.MenuConst;
import com.smfx.yxt.common.enums.OfficialApplyStatus;
import com.smfx.yxt.common.enums.RelationType;
import com.smfx.yxt.common.enums.WorkApprovalType;
import com.smfx.yxt.daoSqlserver.AttachmentListMapper;
import com.smfx.yxt.daoSqlserver.OfficialApplyMapper;
import com.smfx.yxt.daoSqlserver.OrganizeGroupMapper;
import com.smfx.yxt.daoSqlserver.ReqOfficialApplyMapper;
import com.smfx.yxt.daoSqlserver.TeacherInfoMapper;
import com.smfx.yxt.daoSqlserver.WorkApprovalConfMapper;
import com.smfx.yxt.exception.ExpirationException;
import com.smfx.yxt.model.AttachmentList;
import com.smfx.yxt.model.OfficialApply;
import com.smfx.yxt.model.ReqOfficialApply;
import com.smfx.yxt.model.TeacherInfo;
import com.smfx.yxt.model.WorkApprovalConf;
import com.smfx.yxt.page.Page;
import com.smfx.yxt.reqVo.OfficialApplyReqVO;
import com.smfx.yxt.service.IOfficialApplyService;
import com.smfx.yxt.utils.BeanUtils;
import com.smfx.yxt.utils.PropertiesUtil;
import com.smfx.yxt.view.OfficialApplyView;
import com.smfx.yxt.wechat.utils.TemplateUtil;

@Service("officialApplyService")
public class OfficialApplyServiceImpl implements IOfficialApplyService {

	@Autowired
	private OfficialApplyMapper officialApplyMapper;
	@Autowired
	private ReqOfficialApplyMapper reqOfficialApplyMapper;
	@Autowired
	private AttachmentListMapper attachmentListMapper;
	@Autowired
	private TeacherInfoMapper teacherInfoMapper;
	@Autowired
	private WorkApprovalConfMapper workApprovalConfMapper;
	@Autowired
	private OrganizeGroupMapper organizeGroupMapper;
	
	@Override
	public int insertSelective(OfficialApply record) {
		return officialApplyMapper.insertSelective(record);
	}

	@Override
	public OfficialApply selectByPrimaryKey(Integer id) {
		return officialApplyMapper.selectByPrimaryKey(id);
	}

	@Override
	public int updateByPrimaryKeySelective(OfficialApply record) {
		return officialApplyMapper.updateByPrimaryKeySelective(record);
	}

	@Override
	public OfficialApplyView selectViewById(Integer id) {
		OfficialApply apply = officialApplyMapper.selectByPrimaryKey(id);
		OfficialApplyView viewApply = BeanUtils.copyAs(apply, OfficialApplyView.class);
		viewApply.setReqList(reqOfficialApplyMapper.selectListByApplyId(apply.getId()));
		Map<String, Object> map = new HashMap<>();
		map.put("type", RelationType.OFFICIAL.getCode());
		map.put("objId", apply.getId());
		viewApply.setAttachList(attachmentListMapper.queryAttachmentListByRelationId(map));
		return viewApply;
	}

	@Override
	public void addApply(OfficialApplyReqVO vo) {
		OfficialApply apply = BeanUtils.copyAs(vo, OfficialApply.class);
		apply.setCreateTime(new Date());
		apply.setStatus(OfficialApplyStatus.PENDING.getCode());
		officialApplyMapper.insertSelective(apply);
		ReqOfficialApply req = new ReqOfficialApply();
		req.setApplyId(apply.getId());
		req.setTeacherId(apply.getApplyerId());
		req.setTeacherName(apply.getApplyerName());
		req.setStatus(apply.getStatus());
		reqOfficialApplyMapper.insertSelective(req);
		AttachmentList attachment = new AttachmentList();
		attachment.setTeacherId(apply.getApplyerId());
		attachment.setRelationType(RelationType.OFFICIAL.getCode());
		attachment.setRelationId(Long.valueOf(apply.getId()));
		attachmentListMapper.updateRelationId(attachment);
		ThreadExecute(apply);
	}

	@Override
	public void updateAudit(OfficialApplyReqVO vo) {
		OfficialApply apply = officialApplyMapper.selectByPrimaryKey(vo.getId());
		ReqOfficialApply req = new ReqOfficialApply();
		req.setApplyId(vo.getId());
		req.setTeacherId(vo.getApproverId());
		req.setTeacherName(vo.getApproverName());
		req.setRemarks(vo.getRemarks());
		req.setStatus(vo.getStatus());
		if(OfficialApplyStatus.PENDING.getCode().equals(apply.getStatus())) {
			apply.setStatus(vo.getStatus());
			if(vo.getStatus().equals(OfficialApplyStatus.PRINCIPAL_REJECT.getCode())) {
				apply.setApproverId(vo.getApproverId());
				apply.setApproverName(vo.getApproverName());
				apply.setRejectReason(vo.getRemarks());
			}else if(vo.getStatus().equals(OfficialApplyStatus.AGREE.getCode())) {
				if(StringUtils.isBlank(vo.getExecutor())) {
					apply.setStatus(OfficialApplyStatus.OFFICE_AUDITING.getCode());
					req.setStatus(OfficialApplyStatus.OFFICE_AUDITING.getCode());
				}else {
					apply.setApproverId(vo.getApproverId());
					apply.setApproverName(vo.getApproverName());
					apply.setExecutorIds(vo.getExecutorIds());
					apply.setExecutor(vo.getExecutor());
				}
			}
		}else if (OfficialApplyStatus.OFFICE_AUDITING.getCode().equals(apply.getStatus())) {
			apply.setApproverId(vo.getApproverId());
			apply.setApproverName(vo.getApproverName());
			apply.setStatus(vo.getStatus());
			apply.setExecutorIds(vo.getExecutorIds());
			apply.setExecutor(vo.getExecutor());
		}else {
			throw new ExpirationException("公文申请状态已变更，请刷新后再试");
		}
		apply.setUpdateTime(new Date());
		reqOfficialApplyMapper.insertSelective(req);
		int result = officialApplyMapper.updateByIdForVersion(apply);
		if(result == 0) {
			throw new ExpirationException("公文申请状态已变更，请刷新后再试");
		}
		ThreadExecute(apply);
	}

	@Override
	public List<OfficialApply> selectListByPage(Page<OfficialApply> page) {
		return officialApplyMapper.selectListByPage(page);
	}

	void ThreadExecute(OfficialApply apply) {
		TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
	        @Override
	        public void afterCommit() {
	        	String reqUrl = Const.BASEPATH + Const.TEACHER_ROLE + 
						MenuConst.OFFICIAL_APPROVAL + "/detail/" + apply.getId();
	        	String approvalType = "公文审批";
	        	if(OfficialApplyStatus.PENDING.getCode().equals(apply.getStatus())) {
	        		String templateId = PropertiesUtil.getProperty("work_approval_apply_template");
					TeacherInfo teacher = teacherInfoMapper.selectByPrimaryKey(apply.getApproverId());
					TemplateUtil.approvalApplySend(teacher.getOpenid2(), approvalType, apply.getApplyerName(), 
							apply.getApplyContent(), apply.getCreateTime(), templateId, reqUrl);
	        	}else if(OfficialApplyStatus.PRINCIPAL_REJECT.getCode().equals(apply.getStatus())) {
	        		String templateId = PropertiesUtil.getProperty("work_approval_result_template");
	        		String title = "您好！您提交的公文申请已经被审批";
	        		TeacherInfo applyTeacher = teacherInfoMapper.selectByPrimaryKey(apply.getApplyerId());
					TemplateUtil.approvalResultSend(applyTeacher.getOpenid2(), title, approvalType, 
							OfficialApplyStatus.getValue(apply.getStatus()), new Date(), templateId, reqUrl);
	        	}else if(OfficialApplyStatus.OFFICE_AUDITING.getCode().equals(apply.getStatus())) {
	        		String templateId = PropertiesUtil.getProperty("work_approval_result_template");
	        		String title = "您好！有一个新的待处理的公文审批，请及时处理";
	    			WorkApprovalConf record = workApprovalConfMapper.selectByItemCode(WorkApprovalType.OFFICIAL_APPROVAL.getCode());
	    			List<TeacherInfo> approvalList = teacherInfoMapper.selectListByIds(Arrays.asList(record.getApprovalerId().split(",")));
					for(TeacherInfo teacher : approvalList) {
						TemplateUtil.approvalResultSend(teacher.getOpenid2(), title, approvalType, 
								OfficialApplyStatus.getValue(apply.getStatus()), new Date(), templateId, reqUrl);
					}
	        	}else if (OfficialApplyStatus.AGREE.getCode().equals(apply.getStatus())) {
	        		String templateId = PropertiesUtil.getProperty("work_approval_result_template");
	        		String title = "您好！您提交的公文申请已经被审批";
	        		String approvalResult = OfficialApplyStatus.getValue(apply.getStatus());
	        		TeacherInfo applyTeacher = teacherInfoMapper.selectByPrimaryKey(apply.getApplyerId());
					TemplateUtil.approvalResultSend(applyTeacher.getOpenid2(), title, approvalType, 
							approvalResult, new Date(), templateId, reqUrl);
					
					List<TeacherInfo> list = organizeGroupMapper.selectOfficialCcer();
					title = "您好！有一条审批通过的公文申请抄送给您，请注意查收";
					for(TeacherInfo teacher : list) {
						TemplateUtil.approvalResultSend(teacher.getOpenid2(), title, approvalType, 
								approvalResult, new Date(), templateId, reqUrl);
					}
	        	}
	        }
	    });
	}

}
